package middleware

import (
	"bytes"
	"gauss/internal/model"
	"gauss/internal/utils/db"
	"io"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
)

type responseBodyWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer
}

func (r responseBodyWriter) Write(b []byte) (int, error) {
	r.body.Write(b)
	return r.ResponseWriter.Write(b)
}

// OperationLog 操作日志中间件
func OperationLog() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 开始时间
		startTime := time.Now()

		// 获取请求体
		var requestBody []byte
		if c.Request.Body != nil {
			requestBody, _ = io.ReadAll(c.Request.Body)
			c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody))
		}

		// 包装响应写入器
		w := &responseBodyWriter{body: &bytes.Buffer{}, ResponseWriter: c.Writer}
		c.Writer = w

		// 处理请求
		c.Next()

		// 获取用户信息
		userID, _ := c.Get("user_id")
		username, _ := c.Get("username")

		// 获取模块和操作
		path := c.Request.URL.Path
		method := c.Request.Method
		module := strings.Split(strings.Trim(path, "/"), "/")[0]
		action := getAction(method)

		// 创建操作日志
		operationLog := &model.OperationLog{
			UserID:       userID.(uint),
			Username:     username.(string),
			Module:       module,
			Action:       action,
			Method:       method,
			Path:         path,
			IP:          c.ClientIP(),
			UserAgent:    c.Request.UserAgent(),
			RequestBody:  string(requestBody),
			ResponseBody: w.body.String(),
			Status:       c.Writer.Status(),
			CreatedAt:    startTime,
			UpdatedAt:    time.Now(),
		}

		// 异步保存日志
		go func() {
			if err := db.DB.Create(operationLog).Error; err != nil {
				c.Error(err)
			}
		}()
	}
}

// getAction 根据HTTP方法获取操作类型
func getAction(method string) string {
	switch method {
	case "POST":
		return "create"
	case "PUT", "PATCH":
		return "update"
	case "DELETE":
		return "delete"
	default:
		return "query"
	}
} 